#ifndef CORE_API_MANAGER_H_INCLUDED
#define CORE_API_MANAGER_H_INCLUDED

#include <Core/Commands.h>
#include <Common/ConcurrentQueue.h>
#include <Core/BoxApi/IBoxConnection.h>

#include <list>
#include <utility>
#include <boost/thread.hpp>
#include <boost/threadpool.hpp>
#include <boost/noncopyable.hpp>
#include <boost/tuple/tuple.hpp>

namespace Core { namespace BoxApi {

/**
 * The BoxApiManagerParams
 */
struct ApiManagerParams {
	int conccurency;				///< 
	bool connectionCloneAtDone;		///< Close connection when message is sent and response received
};

/**
 * The BoxApiManager provides interface for sending/receiving messages
 * 
 */
class ApiManager : private boost::noncopyable { 
public :
	explicit ApiManager(ApiManagerParams const & params);
	~ApiManager() throw ();

	/** Creates new connection 
	 *  It returns connection object for specified params 
	 */
	IBoxConnectionPtr connect(BoxConnectionParams & params) throw (std::exception);

	/** Posts messages asynchroniously to specified connection
	 *  
	 */
	void postMessage(IBoxConnectionPtr connection, ICommandPtr command) throw (std::exception);
	
	/** Gets next message 
	 * @returns
	 * 		tuple which contains command and connection
	 */
	boost::tuple<ICommandPtr, IBoxConnectionPtr> getNextMessage() throw (std::exception);

	/** Gets messages list with limit count
	 *	Return messages lis available at the moment  
	 */
	std::list<std::pair<ICommandPtr, IBoxConnectionPtr> > 
		getNextMessages(std::size_t maxMessages) throw (std::exception);
		
	/** gets messages count available at the moment */
	std::size_t getMessageCount() const throw ();

	/** Interrupt manager processing */
	void interrupt() throw (std::exception);

private :
	/**
	 * Message item tuple
	 */
	struct MessageQueueBucket {
		ICommandPtr com;			// command pointer
		IBoxConnectionPtr conn;		// conntection pointer
	};
	
	/**
	 * Message queue
	 */
	typedef Common::ConcurrentQueue<MessageQueueBucket> MessageQueueType; 
	
	void sendMessageWrapp(IBoxConnectionPtr connenction, ICommandPtr command); 

	MessageQueueType m_recvQueue;
	boost::threadpool::pool m_pool;
	ApiManagerParams const m_params;
	boost::mutex m_lock;

};

} } // namespace Core, BoxApi

#endif

